home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource3 / 126_01 / martz_ei.c < prev    next >
Text File  |  1985-03-11  |  13KB  |  423 lines

  1. /*********************************************************************\
  2. ** .---------------------------------------------------------------. **
  3. ** |                                                               | **
  4. ** |                                                               | **
  5. ** |         Copyright (c) 1981, 1982, 1983 by Eric Martz.         | **
  6. ** |                                                               | **
  7. ** |                                                               | **
  8. ** |       Permission is hereby granted to use this source         | **
  9. ** |       code only for non-profit purposes. Publication of       | **
  10. ** |       all or any part of this source code, as well as         | **
  11. ** |       use for business purposes is forbidden without          | **
  12. ** |       written permission of the author and copyright          | **
  13. ** |       holder:                                                 | **
  14. ** |                                                               | **
  15. ** |                          Eric Martz                           | **
  16. ** |                         POWER  TOOLS                          | **
  17. ** |                    48 Hunter's Hill Circle                    | **
  18. ** |                      Amherst MA 01002 USA                     | **
  19. ** |                                                               | **
  20. ** |                                                               | **
  21. ** `---------------------------------------------------------------' **
  22. \*********************************************************************/
  23.  
  24. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  25. /* MARTZLIB.C IS A LIBRARY OF FUNCTIONS OF GENERAL USE.
  26.  
  27.     MARTZ-EI.C CONTAINS:
  28.  
  29.         equal(s1,s2)
  30.         fbrkout(width, buf, tnull, force_nl, fpout)
  31.         findwords(s,p)
  32.         firstone(buf,tofind)
  33.     char *fnnlgetl(s,fp,max)
  34.     char *fnnlgets(s,fp)
  35.         freq(buf,item)
  36.     char *ftgets(buf,fp,maxcount)
  37.         getint(string,ptr)
  38.         getwrds(message,wordbuf,pp)
  39.         goodfile(message,name)
  40.         icata(n,stout)
  41.         instr(i,s,t)
  42. */
  43. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  44. equal(s1, s2)
  45.  
  46. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  47.  
  48. /* RETURNS YES IF THE STRINGS IN s1 AND s2 ARE EQUAL, ELSE NO */
  49.  
  50.     char *s1, *s2;
  51.     {
  52.     if (strcmp(s1, s2) EQ 0) return(YES);
  53.     else return(NO);
  54. }
  55. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  56. fbrkout(width, buf, tnull, force_nl, fpout, displayall, indent)
  57.  
  58. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  59.  
  60. /* PUTS INTO fpout CONTENTS OF buf, BROKEN AT SPACES, TABS, OR
  61. NEWLINES INTO LINES OF LENGTH <= width.
  62.  
  63. --->  WARNING!!! FBRKOUT() MODIFIES THE CONTENTS OF buf!!! <---
  64.  
  65. BREAK IS FORCED AT THE STRING force_nl (WHICH IS DELETED FROM
  66. OUTPUT). IF YOU DO NOT WISH TO FORCE BREAKS, CALL WITH 0.
  67.  
  68. IF displayall IS YES, UNPRINTABLE CHARACTERS ARE EXPANDED TO
  69. PRINTABLE FORM.
  70.  
  71. IF indent IS YES, THE 2ND-NTH LINES PUT OUT BY FBRKOUT ARE
  72. INDENTED 5 SPACES.
  73.  
  74. IF TNULL (POINTER TO TERMINAL NULL OF buf) IS NOT AVAILABLE, CALL
  75. WITH ZERO. TNULL IS NOT NECESSARY BUT IMPROVES EFFICIENCY(?). */
  76.  
  77.     char *buf, *tnull, *force_nl;
  78.     int width, displayall, indent;
  79.     FILE *fpout;
  80.     {
  81.     char *brk, out[4];
  82.     int len, force, firstline, lesswidth;
  83.  
  84.     if (force_nl EQ 0) force_nl = "";
  85.     force = ERROR;
  86.     if (tnull EQ 0) tnull = buf + strlen(buf);
  87.     if ((tnull - buf) EQ 0) { /* GUARANTEE NEWLINE FOR EMPTY BUFFER */
  88.         fputs("\n", fpout);
  89.         return(0);
  90.     }
  91.     firstline = YES;
  92.     while ((len = (tnull - buf)) > 0) {
  93.  
  94.         /* INDENT IF NEEDED AND SET lesswidth */
  95.         if (indent AND !firstline) {
  96.             lesswidth = width - 5;
  97.             fputs("     ", fpout); /* 5 spaces */
  98.         }
  99.         else lesswidth = width;
  100.  
  101.         if (len > lesswidth) { /* IF THE LINE IS TOO LONG */
  102.             /* WE'LL ASSUME THERE IS A SPACE BEFORE lesswidth! */
  103.             /* FIND A BREAKPOINT AT A SPACE */
  104.             brk = buf + rindex(buf, " ", lesswidth);
  105.         }
  106.         else brk = tnull;
  107.  
  108.         /* LOOK FOR force_nl */
  109.         if (force_nl[0]) force = instr(0, buf, force_nl);
  110.  
  111.         /* SET BREAK AT WHICHEVER OCCURS FIRST */
  112.         if (force NE ERROR AND (brk > buf + force)) brk = buf + force;
  113.  
  114.         /* BREAK THE BUFFER */
  115.         *brk = NULL;
  116.  
  117.         /* WRITE OUT THE LINE SEGMENT */
  118.         while (*buf) {
  119.             if (displayall) {
  120.                 dispexp(*buf, out);
  121.                 fputs(out, fpout);
  122.             }
  123.             else putc(*buf, fpout);
  124.             buf++;
  125.         }
  126.         fputs("\n", fpout); /* putc() does not expand \n */
  127.  
  128.  
  129.         /* SET THE POINTER PAST END OF STRING */
  130.         buf = brk + strlen(force_nl);
  131.         if(!*force_nl) buf++;
  132.  
  133.         firstline = NO;
  134.     }
  135. }
  136. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  137. findwords(s,p)
  138.  
  139. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  140.  
  141. /* FINDS THE WHITESPACE-DELIMITED WORDS IN STRING "s" (WHERE WHITESPACE
  142. INCLUDES SPACES, TABS AND NEWLINES). RETURNS COUNT OF WORDS FOUND. EACH WORD
  143. IS POINTED TO BY A MEMBER OF THE ARRAY "p". THE STRING POINTED TO BY "s" IS
  144. COMPRESSED INTO WORDS DELIMITED ONLY BY NULLS. THE FIRST WORD IS POINTED TO BY
  145. p[1], NOT p[0]. (p[0] IS WASTED.) */
  146.  
  147.     char *s, **p;
  148.     {
  149.     int wcnt, atend;
  150.     char *beginw, *endw, *nextat;
  151.     blankout(s,"\t\n");
  152.     atend = FALSE;
  153.     wcnt = 0;
  154.     beginw = nextat = s;
  155.     while(1){
  156.         for(;*beginw; beginw++)
  157.             if(*beginw != ' ') break;
  158.         if (!*beginw) return(wcnt);
  159.         for(endw=beginw; *endw; endw++)
  160.             if (*endw == ' ') break;
  161.         if (!*endw) atend = TRUE;
  162.         *endw = '\0';
  163.         wcnt += 1;
  164.         p[wcnt] = nextat;
  165.         if (nextat != beginw) strcpy(nextat,beginw);
  166.         if (atend) return(wcnt);
  167.         nextat += (endw + 1) - beginw;
  168.         beginw = endw + 1;
  169.     }
  170. }
  171. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  172. char *firstone(buf, tofind)
  173.  
  174. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  175.  
  176. /* RETURNS POINTER [NOT AN INDEX!] TO FIRST OCCURRENCE IN buf OF
  177. A CHARACTER INCLUDED IN THE STRING tofind, OR NULL IF NOT FOUND.
  178.  
  179. */
  180.     char *buf, *tofind;
  181.     {
  182.     char *p, *f;
  183.     for (p=buf; *p; p++) {
  184.         f = tofind;
  185.         while (*f)
  186.             if (*p == *(f++))
  187.                 return (p);
  188.     }
  189.     return(0);
  190. }
  191. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  192. char *fnnlgetl(s,fp,max)
  193.  
  194. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  195.  
  196. /* FNNLGET = File-No-NewLine-GET-Longstring
  197.  
  198. SAME AS FTGETS BUT STRING LEFT IN S IS STRIPPED OF THE TERMINAL NEWLINE
  199. AND BUFFER LENGTH IS AN ARGUMENT FOR LONG INPUT LINES */
  200.  
  201.     char *s;
  202.     FILE *fp;
  203.     {
  204.     char *tnull;
  205.     if (!(tnull = ftgets(s,fp,max))) return(0);
  206.     if (*(--tnull) EQ '\n') *tnull = NULL;
  207.     return (tnull);
  208. }
  209. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  210. char *fnnlgets(s,fp)
  211.  
  212. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  213.  
  214. /* FNNLGETS = File-No-NewLine-GET-String
  215.  
  216. SAME AS FTGETS BUT STRING LEFT IN S IS STRIPPED OF THE TERMINAL NEWLINE */
  217.  
  218.     char *s;
  219.     FILE *fp;
  220.     {
  221.     char *tnull;
  222.     if (!(tnull = ftgets(s,fp,MAXLINE))) return(0);
  223.     if (*(--tnull) EQ '\n') *tnull = NULL;
  224.     return (tnull);
  225. }
  226. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  227. freq(buf, item)
  228.  
  229. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  230.  
  231. /* RETURNS THE FREQUENCY OF item IN buf. FREQ IS FOR
  232. NONOVERLAPPING OCCURRENCES. THUS IF buf CONTAINS "...." AND item
  233. CONTAINS  "..", FREQ IS 2 NOT 3. */
  234.  
  235.     char *buf, *item;
  236.     {
  237.     int i, count, start, itemlen;
  238.     count = start = 0;
  239.     itemlen = strlen(item);
  240.     while ((i=instr(start,buf,item)) NE ERROR) {
  241.         count++;
  242.         start = i + itemlen;
  243.     }
  244.     return(count);
  245. }
  246. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  247. char *ftgets(buf,fp,maxcount)
  248.  
  249. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  250.  
  251. /* This is BDSC fgets (from stdlib2.c) with the following modifications:
  252.     Returns pointer to terminal null in buf;
  253.     The buffer length restriction (formerly MAXLINE) has been added as
  254.         an argument.
  255.         
  256. ftgets() retains inclusion of newline in buf (like fgets).
  257.  
  258. */
  259.     char *buf;
  260.     FILE *fp;
  261.     int maxcount;
  262.     {
  263.     int c;
  264.     char *cptr;
  265.     cptr = buf;
  266.     if ( (c = rawgetc(fp)) == CPMEOF || c == EOF) return NULL;
  267.  
  268.     do {
  269.         if ((*cptr++ = c) == '\n') {
  270.             if (cptr>buf+1 && *(cptr-2) == '\r')
  271.                 *(--cptr - 1) = '\n';
  272.             break;
  273.         }
  274.      } while (maxcount-- && (c=rawgetc(fp)) != EOF && c != CPMEOF);
  275.  
  276.     /* N.B. IF GETC IS USED, THE MARTZ MODIFIED VERSION NEVER
  277.     RETURNS CPMEOF HENCE ^Z IS NOT PUSHED BACK AND FTGETS FAILS
  278.     WHEN THE LAST LINE DOES NOT END IN A \r\n! */
  279.     if (c == CPMEOF) ungetc(c,fp);    /* push back control-Z */
  280.  
  281.     *cptr = '\0';
  282.     return (cptr);
  283. }
  284. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  285. getint(string,ptr) 
  286.  
  287. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  288.  
  289. /* Prints "string" suffixed with a "? ", then converts next line
  290. of input to an integer. If integer is valid (-32767 to 32767) it
  291. is stored in the location pointed to by the argument "ptr". If
  292. invalid, a diagnostic is printed, the question in "string" is
  293. repeated, and another line of input is examined. Thus, this
  294. function will not return until a valid integer is obtained.
  295. Nothing is returned (?! Why not return the integer found instead
  296. of making it an argument?). */
  297.  
  298.     char *string;
  299.     int *ptr;
  300.     {
  301.     char numst[MAXLINE];
  302.     int n;
  303.     n = 1;
  304.     while (n != 0) {
  305.         printf("%s? ",string);
  306.         gets(numst);
  307.         n = ati(ptr,numst);
  308.         if (n == -1) printf("Integer not found\n");
  309.         if (n == 1) printf(
  310.             "Absolute value of integer too large: maximum is 32767\n");
  311.     }
  312. }
  313. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  314. getwrds(message, wordbuf, pp)
  315.  
  316. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  317.  
  318. /* PRINTS message, GETS A LINE INTO wordbuf, BLANKS OUT COMMAS,
  319. PUTS NULL DELIMITED WORDS IN wordbuf, LEAVING POINTERS TO EACH IN
  320. pp, RETURNS COUNT OF WORDS FOUND. 
  321.  
  322. CAN BE USED WITH ati() TO GET A SERIES OF ONE OR MORE INTEGERS.
  323.  
  324. */
  325.  
  326.     char *message, *wordbuf, **pp;
  327.     {
  328.     fprintf(STDERR,"%s",message);
  329.     gets(wordbuf);
  330.     blankout(wordbuf,",");
  331.     return (findword(wordbuf,pp));
  332. }
  333. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  334. FILE *goodfile(message, name)
  335.  
  336. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  337.  
  338. /* PRINTS MESSAGE AND INPUTS FILE NAME. THIS IS REPEATED UNTIL
  339. NAME IS A VALID CP/M FILENAME AND IS SUCCESSFULLY OPENED FOR
  340. READING. SUPPLIES *name AND RETURNS FILE POINTER. */
  341.     
  342.     char *message, *name;
  343.     {
  344.     FILE *fp;
  345.     int check;
  346.     char *pp[16], buf[MAXLINE];
  347.     check = 0;
  348.     while (check NE 1) {
  349.         check = getwrds(message, buf, pp);
  350.         if (check NE 1) {
  351.             fprintf(STDERR,"Single name please.\n");
  352.             continue;
  353.         }
  354.         if (badname(pp[1])) {
  355.             check = 0;
  356.             continue;
  357.         }
  358.         strcpy(name,pp[1]);
  359.         fp = fopen(name,"r-");
  360.         if (fp EQ 0) {
  361.             check = 0;
  362.             fprintf(STDERR,"File \"%s\" does not exist.\n",name);
  363.         }
  364.     }
  365.     return(fp);
  366. }
  367. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  368. icata(n,stout)
  369.  
  370. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  371.  
  372. /* The integer "n" is converted to an ascii string which is appended
  373. (concatenated) onto the end of the null-terminated string in "stout". */
  374.  
  375.         int n;
  376.         char *stout;
  377.         {
  378.         char s[12];
  379.         int i, sign;
  380.         if ((sign=n)<0) n = -n;
  381.         i=0;
  382.         do {
  383.                 s[i++] = n % 10 + '0';
  384.         } while ((n /= 10)>0);
  385.         if (sign<0) s[i++] = '-';
  386.         s[i]='\0';
  387.         reverse(s);
  388.         strcat(stout,s);
  389. }
  390. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  391. instr(i,s,t)
  392.  
  393. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  394.  
  395. /* Finds first occurrence of string "t" in "s", and returns the
  396. index (position in "s" where "t" begins). Returns -1 if "t" is
  397. not found in "s" or if "t" is a null string. The search for "t"
  398. begins at the "i"th position in "s".
  399.  
  400. This is "jindex" modified to begin at the "i"th position; also
  401. modified because unlike instr "jindex" returns 0 if "t" is a null
  402. string. */
  403.  
  404. char s[], t[];
  405. int i;
  406. {       register char *p1, *p2, *p3;
  407.         if (!*t)
  408.                 return(-1);
  409.         for (p1 = s+i; *p1; p1++)
  410.                 if (*p1 == *t) {
  411.                     for (p2 = p1+1, p3 = t+1; *p3 && *p2 == *p3; p2++, p3++);
  412.                      if (!*p3)
  413.                                 return(p1 - s);
  414.                 }
  415.         return(-1);
  416. }
  417. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  418. /*    END OF MARTZ-EI.C    */
  419. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  420. +++++++*/
  421. instr(i,s,t)
  422.  
  423. /* Copyright (